﻿using System;
using smp.ButterflyCakes.Models;
using smp.ButterflyCakes.Models.ViewModels.Attachments;
using smp.ButterflyCakes.Repository.Databases;
using smp.ButterflyCakes.Repository.Interfaces;
using smp.QueryDb;
using smp.QueryDb.Executing;

namespace smp.ButterflyCakes.Repository.Implementation
{
    public class AttachmentRespository : IAttachmentRepository
    {
        private readonly IDbSessionFactory _sessionFactory;

        public AttachmentRespository()
        {
            _sessionFactory = new DbSessionFactory("ButterflyCakes");
        }

        public ViewFilesView GetFilesView(Guid orderId, bool canManage)
        {
            using (var session = _sessionFactory.Create())
            {
                var data = session.Query(new Query<ViewFilesDataItem>()
                                             .From(Db.Attachments)
                                             .Map(x => x.FileId).To(Attachments.Id)
                                             .Map(x => x.IsImage).To(Attachments.IsImage)
                                             .Map(x => x.OrderId).To(Attachments.OrderId)
                                             .Map(x => x.Desription).To(Attachments.Description)
                                             .Map(x => x.Name).To(Attachments.FileName)
                                             .Where(
                                                 new Filter<ViewFilesDataItem>(Attachments.OrderId).Is.EqualTo(orderId)));
                var diagrams = session.Query(new Query<DiagramItem>()
                                                 .From(Db.Diagram)
                                                 .Map(x => x.ComponentId).To(Diagram.ComponentId)
                                                 .Map(x => x.Description).To(Diagram.Description)
                                                 .Map(x => x.Html).To(Diagram.Html)
                                                 .Map(x => x.Id).To(Diagram.Id)
                                                 .Map(x => x.OrderId).To(Diagram.OrderId)
                                                 .Where(new Filter<DiagramItem>(Diagram.OrderId).Is.EqualTo(orderId)));
                return new ViewFilesView(orderId, data.Results, diagrams.Results, canManage);
            }
        }

        public bool AddAttachment(Guid orderId, AttachementItem attachement)
        {
            using (var session = _sessionFactory.Create())
            {
                var result = session.Insert(new Insert(Db.Attachments)
                                                .Set(Attachments.Description).To(attachement.Description)
                                                .Set(Attachments.FileContent).To(attachement.Content)
                                                .Set(Attachments.FileExtension).To(attachement.Extension)
                                                .Set(Attachments.FileName).To(attachement.Name)
                                                .Set(Attachments.Id).To(attachement.Id)
                                                .Set(Attachments.IsImage).To(attachement.IsImage)
                                                .Set(Attachments.OrderId).To(attachement.OrderId)
                                                .Set(Attachments.MimeType).To(attachement.MimeType));
                return result == 1;
            }
        }

        public Guid DeleteAttachment(Guid attachmentId)
        {
            Guid orderId;
            using (var session = _sessionFactory.Create())
            {
                var attachment = session.Load(new Query()
                                                  .From(Db.Attachments)
                                                  .Select(Attachments.OrderId)
                                                  .Where(new Filter(Attachments.Id).Is.EqualTo(attachmentId)));
                if (attachment == null)
                    return Guid.NewGuid();
                orderId = new Guid(attachment.Value("OrderId").ToString());
                session.Delete(new Delete(Db.Attachments).Where(new Filter(Attachments.Id).Is.EqualTo(attachmentId)));
            }
            return orderId;
        }

        public AttachementItem GetAttachment(Guid fileId)
        {
            using (var session = _sessionFactory.Create())
            {
                return session.Load(new Query<AttachementItem>()
                                        .From(Db.Attachments)
                                        .Map(x => x.Id).To(Attachments.Id)
                                        .Map(x => x.IsImage).To(Attachments.IsImage)
                                        .Map(x => x.OrderId).To(Attachments.OrderId)
                                        .Map(x => x.Content).To(Attachments.FileContent)
                                        .Map(x => x.Extension).To(Attachments.FileExtension)
                                        .Map(x => x.Name).To(Attachments.FileName)
                                        .Map(x => x.Description).To(Attachments.Description)
                                        .Map(x => x.MimeType).To(Attachments.MimeType)
                                        .Where(new Filter<AttachementItem>(Attachments.Id).Is.EqualTo(fileId)));
            }
        }

        public byte[] GetImageContent(Guid imageId)
        {
            var attachement = GetAttachment(imageId);
            if (!attachement.IsImage)
                return null;
            return attachement.Content;
        }
    }
}
